はじめてのBlenderアドオン開発
Last Update: 2023.3.1
Blender 2.7
はじめてのBlenderアドオン開発
Blender 2.7
Last Update: 2023.3.1
2-2. 複数のオペレータクラスを登録する
2-1節 ではアドオン開発の基本的な部分について説明しました。 本節では前回解説した内容を理解していることを前提に、2-1節 よりも複雑なサンプルを用いて、複数のメニュー項目を追加する方法を解説します。 既に解説済みの部分は説明を省略しますので、不明な点がある場合は 2-1節 に戻って確認してください。
本節で作成するアドオンの仕様は以下の通りです。
1-5節 を参考にして以下のソースコードを入力し、ファイル名 sample_2_2.py
で保存します。
import bpy
bl_info = {
"name": "サンプル2-2: オブジェクトを拡大・縮小するアドオン",
"author": "Nutti",
"version": (2, 0),
"blender": (2, 75, 0),
"location": "3Dビュー > オブジェクト",
"description": "オブジェクトを拡大・縮小するサンプルアドオン",
"warning": "",
"support": "TESTING",
"wiki_url": "",
"tracker_url": "",
"category": "Object"
}
# オブジェクトを拡大するオペレーション
class EnlargeObject(bpy.types.Operator):
bl_idname = "object.enlarge_object"
bl_label = "選択オブジェクトの拡大"
bl_description = "選択中のオブジェクトを拡大します"
bl_options = {'REGISTER', 'UNDO'}
# メニューを実行した時に呼ばれるメソッド
def execute(self, context):
active_obj = context.active_object
active_obj.scale = active_obj.scale * 2.0
self.report({'INFO'}, "サンプル2-2: 「%s」を2倍に拡大しました。" % (active_obj.name))
print("サンプル2-2: オペレーション「%s」が実行されました。" % (self.bl_idname))
return {'FINISHED'}
# オブジェクトを縮小するオペレーション
class ReduceObject(bpy.types.Operator):
bl_idname = "object.reduce_object"
bl_label = "選択オブジェクトの縮小"
bl_description = "選択中のオブジェクトを縮小します"
bl_options = {'REGISTER', 'UNDO'}
# メニューを実行した時に呼ばれる関数
def execute(self, context):
active_obj = context.active_object
active_obj.scale = active_obj.scale * 0.5
self.report({'INFO'}, "サンプル2-2: 「%s」を1/2倍に縮小しました。" % (active_obj.name))
print("サンプル2-2: オペレーション「%s」が実行されました。" % (self.bl_idname))
return {'FINISHED'}
# メニューを構築する関数
def menu_fn(self, context):
self.layout.separator()
self.layout.operator(EnlargeObject.bl_idname)
self.layout.operator(ReduceObject.bl_idname)
# アドオン有効化時の処理
def register():
bpy.utils.register_module(__name__)
bpy.types.VIEW3D_MT_object.append(menu_fn)
print("サンプル2-2: アドオン「サンプル2-2」が有効化されました。")
# アドオン無効化時の処理
def unregister():
bpy.types.VIEW3D_MT_object.remove(menu_fn)
bpy.utils.unregister_module(__name__)
print("サンプル2-2: アドオン「サンプル2-2」が無効化されました。")
# メイン処理
if __name__ == "__main__":
register()
1-5節 を参考にして、作成したアドオンを有効化します。
アドオンが有効化されると、コンソールウィンドウに以下の文字列が出力されるはずです。
サンプル2-2: アドオン「サンプル2-2」が有効化されました。
アドオン有効化後、[3Dビュー] エリアのメニューに [オブジェクト] > [選択オブジェクトの拡大] と、[オブジェクト] > [選択オブジェクトの縮小] が追加されていることを確認します。
以下の手順に従い、作成したアドオンの機能を使ってみます。
1 | Blender起動直後に自動的に生成されているオブジェクト [Cube] を選択し、[3Dビュー] エリアのメニューである、[オブジェクト] > [選択オブジェクトの拡大] を実行します。選択したオブジェクト [Cube] のサイズが2倍に拡大されます この時、スクリプト実行ログには以下のメッセージが出力されます。 サンプル2-2: 「Cube」を2倍に拡大しました。 また、コンソールウィンドウにも以下のメッセージが出力されます。 サンプル2-2: オペレーション「OBJECT_OT_enlarge_object」が実行されました。 |
2 | [情報] エリアのメニューである、[ファイル] > [新規] を実行し、[スタートアップファイルの再読み込み] を行った後、[3Dビュー] エリアのメニューである、[オブジェクト] > [選択オブジェクトの縮小] を実行します。選択中のオブジェクト [Cube] のサイズが1/2倍に縮小されます。 この時、スクリプト実行ログには以下のメッセージが出力されます。 サンプル2-2: 「Cube」を1/2倍に縮小しました。 また、コンソールウィンドウには以下のメッセージが出力されます。 サンプル2-2: オペレーション「OBJECT_OT_reduce_object」が実行されました。 |
1-5節 を参考に、有効化したアドオンを無効化します。
アドオンを無効化すると、コンソールウィンドウに以下の文字列が出力されます。
サンプル2-2: アドオン「サンプル2-2」が無効化されました。
アドオンの動作を確認したところで、次にソースコードの解説をします。 ここでは、前節で説明した内容から新しく追加された部分について説明します。
本節で新たに加わった処理の1つとして、複数のオペレータクラスを定義する処理があります。
1つのファイルに複数のオペレータクラスを定義するためには、作りたい機能の数だけオペレーションクラスを定義する 必要があります。 本節のサンプルでは、オブジェクトの拡大とオブジェクトの縮小の2つの機能のために、2つのオペーレーションクラスを以下のように作成しました。
# オブジェクトを拡大するオペレーション
class EnlargeObject(bpy.types.Operator):
bl_idname = "object.enlarge_object"
bl_label = "選択オブジェクトの拡大"
bl_description = "選択中のオブジェクトを拡大します"
bl_options = {'REGISTER', 'UNDO'}
# オブジェクトを縮小するオペレーション
class ReduceObject(bpy.types.Operator):
bl_idname = "object.reduce_object"
bl_label = "選択オブジェクトの縮小"
bl_description = "選択中のオブジェクトを縮小します"
bl_options = {'REGISTER', 'UNDO'}
bl_idname
はオペレータクラスごとに固有の文字列を指定する必要があるため、重複しないように気をつけてください。 重複しないようにするための方法は、後ほど紹介します。
オペレータクラスの execute
メソッドの処理の中には、メニューが実行された時にスクリプト実行ログへメッセージを出力する処理が含まれています。
ここでは、EnlargeObject
クラスの execute
メソッド内に定義されている、スクリプト実行ログへメッセージを出力する処理について説明します。
# メニューを実行した時に呼ばれるメソッド
def execute(self, context):
active_obj = context.active_object
active_obj.scale = active_obj.scale * 2.0
self.report({'INFO'}, "サンプル2-2: 「%s」を2倍に拡大しました。" % (active_obj.name))
print("サンプル2-2: オペレーション「%s」が実行されました。" % (self.bl_idname))
return {'FINISHED'}
execute
メソッドに渡されてくる引数については、2-1節 で説明しましたので、引数の詳細についての説明はここでは省略します。 引数 context
から、現在のコンテキスト(実行状態)を取得することができます。
現在選択されているオブジェクトである context.active_object
を active_obj
に一度保存し、active_obj.scale
を2倍にすることで取得したオブジェクトのサイズを2倍に拡大することができます。
その後 self.report
メソッドを用いて、ユーザに対してオペレーションを実行した後に、オブジェクトを拡大・縮小したことがわかるようなメッセージをスクリプト実行ログに出力します。 ここで、execute
メソッドの引数である self
は、オブジェクトのインスタンスです。
self.report
メソッドに指定する必要のある引数を以下に示します。
引数 | 値の型 | 値の説明 |
---|---|---|
第1引数 | 集合型 | 出力メッセージの種類 |
第2引数 | 文字列 | メッセージ本文 |
表示したいメッセージの内容に応じてメッセージの種類を指定し、スクリプト実行ログへ出力することができます。 出力メッセージの種類には例えば以下のようなものがあります。
種類 | コンソールウィンドウへの出力 | 情報ウィンドウのメニューへの出力 |
---|---|---|
INFO |
ハイライト表示(緑色) | 通知メッセージ |
WARNING |
ハイライト表示(橙色) | 警告メッセージ |
ERROR |
ハイライト表示(赤色) | エラーメッセージ |
OPERATOR |
表示 | (なし) |
本節のサンプルでは、オブジェクトが拡大・縮小されたことをユーザへ知らせるために {'INFO'}
を指定し、拡大・縮小したオブジェクト名(active_obj.name
)も表示しています。
bl_idname
が重複してはならないと説明しましたが、bl_idname
が重複していないかを確認するためにはどのようにしたら良いのでしょうか? すでに存在する bl_idname
を確認したい時に役に立つのが、Pythonコンソールです。
Pythonコンソールを利用することにより、例えば以下のようなことができます。
ここではPythonコンソールを使って、本節のサンプルで追加したオペレータクラスの bl_idname
が既存のAPIと重複していないかを実際に確認してみます。 確認対象とする bl_idname
は object.enlarge_object
とします。
Blenderのエリア構成が 1-3節 で紹介したような設定となっていれば、左上のウィンドウが [Pythonコンソール] エリアとなります。
1 | 設定したオペレータクラスの bl_idname が bpy.ops.<オペレーションクラスのbl_idname> に登録されることを利用します。[Pythonコンソール] エリアに bpy.ops.object.enlarge_obje と入力してみます。入力が完了したら、WindowsやLinuxであれば [Ctrl] + [Space]、Macであれば [control] + [space] を押します。ここで単語が補完されなければ、bl_idname として bpy.ops.object.enlarge_object が利用されていないことになり、bl_idname への指定が可能であることがわかります。 |
2 | 本節で作成したアドオンを有効化した後に、Pythonコンソールに以下を打ち込んで [Enter] キーを押します。bpy.ops.object.enlarge_object [3Dビュー] エリアのメニューである、[オブジェクト] > [選択オブジェクトの拡大] を実行した時と同様の効果が得られます。このようにオペレータクラスを登録すると、オペレータクラスの bl_idname が bpy.ops.<オペレーションクラスのbl_idname> として登録されることがわかります。 |
[Pythonコンソール] エリアではショートカットキーが利用できますので、作業効率化のためにぜひ活用してください。
Windows | Mac | Linux | 動作 |
---|---|---|---|
Shift + F4 | shift + fn + F4 | Shift + F4 | Python Consoleを開く |
↑ | ↑ | ↑ | 過去に入力した履歴を戻る |
↓ | ↓ | ↓ | 過去に入力した履歴を進める |
Tab | tab | Tab | インデント |
Shift + tab | shift + tab | shift + tab | アンインデント |
Home | ⌘ + ← | Home | 行頭にカーソルを移動 |
End | ⌘ + → | End | 行末にカーソルを移動 |
Ctrl + ← | control + ← fn + ← |
Ctrl + ← | 単語単位で左にカーソルを移動 |
Ctrl + → | control + → fn + → |
Ctrl + → | 単語単位で右にカーソルを移動 |
Ctrl + Backspace | control + delete | Ctrl + Backspace | カーソルの位置から行頭に向かって単語単位で削除 |
Ctrl + Delete | control + fn +delete | Ctrl + Delete | カーソルの位置から行末に向かって単語単位で削除 |
Shift + Enter | shift + return | Shift + Enter | 行を削除 |
Ctrl + Space | control + space | Ctrl + Space | ソースコード補完 |
Ctrl + ↑ Ctrl + ↓ |
control + ↑ control + ↓ |
Ctrl + ↑ Ctrl + ↓ |
コンソールウィンドウのフルスクリーン化/解除 |
Ctrl + C | control + C | Ctrl + C | 選択部分をクリップボードへコピー |
Ctrl + V | control + V | Ctrl + V | クリップボードからの貼り付け |
Shift + Ctrl + C | shift + control + C | Shift + Ctrl + C | Python Consoleで実行されたスクリプトを全てコピー。 実行結果についてもコピーされるが、行頭に「#~ 」が自動的についてコメント化される |
※ ⌘はMacのcommandを指す
Macでショートカットキーを利用するためには、Macのショートカットキーに標準で割り当てられているcontrolと⌘キーについて、以下の手順に沿って割り当てを解除する必要があります。
1 | [システム環境設定...] をクリック |
2 | [キーボード] をクリック |
3 | [ショートカットタブ] をクリック |
4 | [Pythonコンソール] で使いたいショートカットキーの割り当てを解除 |
本節では、複数のオペレータクラスを作る方法やスクリプト実行ログにメッセージを出力する方法を紹介しました。 さらに、Pythonコンソールの利用方法を紹介しました。 Pythonコンソールを利用することでAPIやテストしたい処理を直接実行して動作確認できることから、アドオン開発の効率化のために積極的に活用していきましょう。
self.report
メソッドを利用することで、スクリプト実行ログにメッセージを出力することができるbl_idname
は bpy.ops.<bl_idname>
に登録される